import _ from "lodash";
import fs from "fs";
import path from "path";

const convertDbTypeToJavaType = (imports, column) => {
  const dbType = column.type;
  // 提取基础类型（忽略长度等参数）
  const baseType = dbType.split("(")[0].toUpperCase();
  const mappings = {
    INT: "Integer",
    BIGINT: "Long",
    VARCHAR: "String",
    TEXT: "String",
    DATETIME: "LocalDateTime",
    DATE: "LocalDate",
    TIME: "LocalTime",
    DECIMAL: "BigDecimal",
    FLOAT: "Float",
    DOUBLE: "Double",
    BOOLEAN: "Boolean",
    BLOB: "byte[]",
    ENUM: "String",
  };
  const importMap = {
    LocalDateTime: ['java.time.LocalDateTime'],
    LocalDate: ['java.time.LocalDate'],
    LocalTime: ['java.time.LocalTime'],
    BigDecimal: ['java.math.BigDecimal'],
  }
  const result = mappings[baseType] || "Object";
  imports.push(...(importMap[result]||[]))
  return result;
};

function foreignKey(table,column) {
  return table.foreignKeys.find(i=>i.columns.includes(column.name))
}

function createColumn(imports, data, table, column, packageStr) {
  let str = "";
  if (column.isNullable) {
    str += "    @Null\n";
  }
  const dataType = convertDbTypeToJavaType(imports, column);
  const foreign = foreignKey(table,column);
  if (column.isPrimaryKey) {
    str += `    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)`+'\n';
  if (dataType == "Long") {
    imports.push("org.babyfish.jimmer.jackson.JsonConverter");
    imports.push("org.babyfish.jimmer.jackson.LongToStringConverter");
    str += "    @JsonConverter(LongToStringConverter.class)\n";
  }
  }
  if(foreign&&(foreign.type=='OneToOne'||foreign.type=='ManyToOne')){
    str+='    @IdView\n'
  }
  str += `    ${dataType} ${_.camelCase(column.name)}();
`;
  if(column.enum){
    
    
  }
    if(foreign){
      
      if(foreign.type=='OneToOne'||foreign.type=='ManyToOne'){
        imports.push(packageStr+"."+_.upperFirst(_.camelCase(foreign.references.table)));
        str +=`    /**
     * ${column.comment} 映射
     * @return ${column.comment} 映射
     */
    @${foreign.type}
    @JoinColumn(name = "${foreign.references.columns[0]}")
    ${_.upperFirst(_.camelCase(foreign.references.table))} ${_.camelCase(foreign.references.table)}();
`;
      }
      if(foreign.type=='OneToMany'){
        imports.push(packageStr+"."+_.upperFirst(_.camelCase(foreign.references.table)));
        imports.push('java.util.List');
        str += `    /**
     * ${column.comment} 短ID
     * @return ${column.comment} 短ID
     */
    @IdView("${_.camelCase(foreign.references.table)}")
    List<${dataType}> ${_.camelCase(foreign.references.table)}Ids();
    
`;
        str+=`    /**
     * ${column.comment} 映射
     * @return ${column.comment} 映射
     */
    @OneToMany(mappedBy = "${_.camelCase(table.name)}")
    List<${_.upperFirst(_.camelCase(foreign.references.table))}> ${_.camelCase(foreign.references.table)}();`
      }
      if(foreign.type=='ManyToMany'){
        imports.push(packageStr+"."+_.upperFirst(_.camelCase(foreign.references.table)));
        imports.push('java.util.List');
        str += `    /**
     * ${column.comment} 短ID
     * @return ${column.comment} 短ID
     */
    @IdView("${_.camelCase(foreign.references.table)}")
    List<${dataType}> ${_.camelCase(foreign.references.table)}Ids();
    
`;
        str+=`    /**
     * ${column.comment} 映射
     * @return ${column.comment} 映射
     */
    @ManyToMany
    @JoinTable(
        name = "${ _.kebabCase(table.name).toUpperCase()}_${ _.kebabCase(foreign.references.table).toUpperCase()}_MAPPING",
        joinColumnName = "${ _.kebabCase(table.name).toUpperCase()}_ID",
        inverseJoinColumnName = "${ _.kebabCase(foreign.references.table).toUpperCase()}_ID"
    )
    List<${_.upperFirst(_.camelCase(foreign.references.table))}> ${_.camelCase(foreign.references.table)}();`
      }
  
    }


  return `    /**
     * ${column.comment}
     * @return ${column.comment}
     */
${str}
`;
}
function createContent(imports, data, table, packageStr) {
  imports.push("org.babyfish.jimmer.sql.*");
  const columns = table.columns.map((column) =>
    createColumn(imports, data, table, column, packageStr)
  );
  const columnsStr = columns.join("\n") + "\n\n";
  const importsStr = imports.map((it) => `import ${it};`).join("\n") + "\n\n";
  return `package ${packageStr};

${importsStr}
/**
 * ${table.description} 实体类
 * @author ${data.info.author}
 * @since ${data.since}
 */
@Entity
@KeyUniqueConstraint
public interface ${_.upperFirst(_.camelCase(table.name))} {
${columnsStr}
}
    `;
}
export default (config, data, params) => {
  data.model.tables.forEach((table) => {
    const imports = [];
    const fileName = _.upperFirst(_.camelCase(table.name)) + ".java";
    const dirPath = path.resolve(params.path);
    fs.mkdirSync(dirPath, { recursive: true });
    const rendered = createContent(imports, data, table, params.package);
    fs.writeFileSync(path.resolve(dirPath, fileName), rendered);
    console.log(`写入${table.description}的${params.name}`);
  });
};
